#include "../StdInc.h"

namespace GSTrader
{
	namespace TradeStrategy
	{
		CSpreadInstrumentStrategy::CSpreadInstrumentStrategy(CStrategySession* pStrategySession, string strStrategyName) :
			CStrategy(pStrategySession, strStrategyName)
		{
			m_pSpreadInstrument = NULL;
		}


		CSpreadInstrumentStrategy::~CSpreadInstrumentStrategy()
		{
		}

		void CSpreadInstrumentStrategy::AddInstance(CSpreadInstrumentStrategy* pStrategy, CSpreadInstrument* pSpreadInstrument)
		{
			if (pSpreadInstrument == NULL || pSpreadInstrument == NULL || pSpreadInstrument->m_nID < 0)
			{
				assert(false);
				return;
			}

			pStrategy->m_pSpreadInstrument = pSpreadInstrument;

			//int i = 0;
			for (auto x : pSpreadInstrument->m_lLeg)
			{
				if (x->m_nInstrumentId < 0)
				{
					assert(false);
					continue;
				}

				CInstrument* pInstrument = m_pFramework->m_pInstrumentManager->GetInstrumentById(x->m_nInstrumentId);
				if (pInstrument == NULL)
				{
					assert(false);
					continue;
				}

				pStrategy->m_pInstruments->Add(x->m_nInstrumentId);

				CTradeProvider* pTradeProvider = GetStrategyTradeProvider(this, pInstrument);
				CMarketDataProvider* pMarketDataProvider = GetStrategyMarketDataProvider(this, pInstrument);
				if (pTradeProvider == NULL || pMarketDataProvider == NULL)
				{
					assert(false);
					continue;
				}

				m_mapTradeProvider[x->m_nIndex] = pTradeProvider;
				m_mapMarketDataProvider[x->m_nIndex] = pMarketDataProvider;

				pStrategy->m_pPortfolio->CreatePosition( pInstrument->m_nID, NULL, NULL);

				//	i++;
			}

			AddStrategy(pStrategy);
			pStrategy->m_nStatus = rsRunning;
			pStrategy->OnStrategyInit();
			pStrategy->OnStrategyStart();
		}

		void CSpreadInstrumentStrategy::StrategyInit()
		{
			if (!m_bInitialized)
			{
				for (auto x : m_pInstruments->m_vInstrumentId)
				{
					CInstrument* pInstrument = m_pFramework->m_pInstrumentManager->GetInstrumentById(x);
					if (!pInstrument || pInstrument->m_nType != insSelfSpread)
					{
						assert(false);
						continue;
					}

					CSpreadInstrument* pSpreadInstrument = (CSpreadInstrument*)pInstrument;
					string strStrategyName = m_strStrategyName + "(" + pSpreadInstrument->m_strSymbol + ")";
					CSpreadInstrumentStrategy* pSpreadInstrumentStrategy = CreateInstance(m_pStrategySession, strStrategyName);
					assert(pSpreadInstrumentStrategy != NULL);

					AddInstance(pSpreadInstrumentStrategy, pSpreadInstrument);
				}

				m_bInitialized = true;
			}
		}

		void CSpreadInstrumentStrategy::DoStart()
		{
			m_nStatus = rsRunning;

			if (m_bDispatchMsg)
			{
				OnStrategyStart();
			}

			for (auto p : m_mapStrategyById)
			{
				CStrategyBase* pStrategy = p.second;
				StrategySubscribe(pStrategy, pStrategy->m_pInstruments, pStrategy->m_nId);
				pStrategy->DoStart();
			}
		}

		CLeg* CSpreadInstrumentStrategy::GetMainLeg()
		{
			if (m_pSpreadInstrument == NULL || m_pSpreadInstrument->GetLegCount() == NULL)
				return NULL;

			for (auto p : m_pSpreadInstrument->m_lLeg)
			{
				if (p->m_bMain)
					return p;
			}

			return NULL;
		}

		CLeg* CSpreadInstrumentStrategy::GetLeg(int nInstrumentId)
		{
			if (m_pSpreadInstrument == NULL || m_pSpreadInstrument->GetLegCount() == NULL)
				return NULL;

			return m_pSpreadInstrument->GetLegById(nInstrumentId);
		}

		CLeg* CSpreadInstrumentStrategy::GetLegByIndex(int nIndex)
		{
			if (m_pSpreadInstrument == NULL || m_pSpreadInstrument->GetLegCount() == NULL)
				return NULL;

			return m_pSpreadInstrument->GetLeg(nIndex);
		}

	}
}